package com.self.home.colorlinez.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.blankj.utilcode.utils.ToastUtils;
import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.view.IconicsImageView;
import com.self.home.colorlinez.R;
import com.self.home.colorlinez.dto.SpaceItemDTO;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import mehdi.sakout.fancybuttons.FancyButton;

public class GameLayout extends RelativeLayout implements View.OnClickListener {


    private static final int[] BALL_COLOR = new int[]{
            0xff009933, 0xff0066CC, 0xff666633, 0xff660033, 0xff993333, 0xff9999CC, 0xffFFCC33
    };

    private int[] nextColors;

    private FancyButton[][] itemContainerArray;

    private int width;
    private int height;

    private final int ROW = 9;

    private ShowNextBallListener showNextBallListener;

    private ScoreChangeListener scoreChangeListener;

    RelativeLayout insideContainerLayout;

    private YoYo.YoYoString selectedBallYoYo;

    private SpaceItemDTO waitMoveSpaceItemDTO;

    private int score = 0;


    public GameLayout(Context context) {
        super(context);
        init();
    }

    public GameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void restartGame() {
        score = 0;
        if (scoreChangeListener != null) {
            scoreChangeListener.onAddScore(0);
        }
        this.removeAllViews();
        initGrid();
    }

    private void init() {
        this.post(() -> {
            int height = this.getMeasuredHeight();
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) this.getLayoutParams();
            layoutParams.height = height;
            layoutParams.width = height;
            GameLayout.this.width = height;
            GameLayout.this.height = height;
            this.setLayoutParams(layoutParams);

            initGrid();
        });
    }

    private void initGrid() {
        int itemHeight = (height) / ROW;

        itemContainerArray = new FancyButton[ROW][ROW];

        insideContainerLayout = new RelativeLayout(getContext());
        RelativeLayout.LayoutParams insideLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        insideContainerLayout.setLayoutParams(insideLayoutParams);
        insideLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        this.addView(insideContainerLayout);

        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                FancyButton itemLayout = new FancyButton(getContext());
                itemLayout.setBorderWidth(1);
                itemLayout.setBorderColor(getResources().getColor(R.color.colorGrey));
                itemLayout.setText("");
                itemLayout.setBackgroundColor(Color.WHITE);

                RelativeLayout.LayoutParams layoutParams = new LayoutParams(itemHeight, itemHeight);
                layoutParams.topMargin = i * itemHeight;
                layoutParams.leftMargin = j * itemHeight;
                itemLayout.setLayoutParams(layoutParams);
                insideContainerLayout.addView(itemLayout);

                itemLayout.setTag(buildEmptySpaceDTO(itemHeight, i, j, 0));

                itemContainerArray[i][j] = itemLayout;

                itemLayout.setOnClickListener(this);
            }
        }

        showNextBall();
    }

    private int[] getNextColors() {
        if (nextColors != null) {
            return nextColors;
        }
        nextColors = new int[3];
        int max = BALL_COLOR.length - 1, min = 0;
        for (int i = 0; i < 3; i++) {
            int index = (int) (Math.random() * (max - min) + min);
            nextColors[i] = BALL_COLOR[index];
        }
        if (this.showNextBallListener != null) {
            this.showNextBallListener.nextBall(nextColors);
        }
        return nextColors;
    }


    @Override
    public void onClick(View view) {
        FancyButton fancyButton = (FancyButton) view;
        SpaceItemDTO spaceItemDTO = (SpaceItemDTO) view.getTag();
        if (spaceItemDTO.isHasBall()) {

            if (spaceItemDTO.isSelected()) {
                if (selectedBallYoYo != null) {
                    selectedBallYoYo.stop();
                }
                spaceItemDTO.setSelected(false);
            } else {
                if (selectedBallYoYo != null && waitMoveSpaceItemDTO != null) {
                    selectedBallYoYo.stop();
                    waitMoveSpaceItemDTO.setSelected(false);
                }
                spaceItemDTO.setSelected(true);

                waitMoveSpaceItemDTO = spaceItemDTO;

                selectedBallYoYo = YoYo.with(Techniques.Bounce)
                        .duration(1500)
                        .repeatMode(ValueAnimator.INFINITE)
                        .repeat(Integer.MAX_VALUE)
                        .playOn(spaceItemDTO.getBall());
            }
        } else if (selectedBallYoYo != null && waitMoveSpaceItemDTO != null) {
            selectedBallYoYo.stop();

            List<FancyButton> pathList = findPathToDest(itemContainerArray[waitMoveSpaceItemDTO.getYNum()][waitMoveSpaceItemDTO.getXNum()], fancyButton, getBallMap());
            if (!pathList.isEmpty()) {
                movePath(pathList, new FinishCarton() {
                    @Override
                    public void end() {
                        spaceItemDTO.setHasBall(true);
//                        spaceItemDTO.setBall(waitMoveSpaceItemDTO.getBall());
//                        spaceItemDTO.setBallColor(waitMoveSpaceItemDTO.getBallColor());
                        waitMoveSpaceItemDTO.setSelected(false);
                        waitMoveSpaceItemDTO.setHasBall(false);
                        waitMoveSpaceItemDTO.setBallColor(0);
                        waitMoveSpaceItemDTO.setBall(null);
                        waitMoveSpaceItemDTO = null;
                        selectedBallYoYo = null;

                        checkAndClearBall(fancyButton);
                        showNextBall();
                        postDelayed(() -> {
                            if (isGameOver()) {
                                ToastUtils.showLongToast(getContext(), "游戏结束");
                                restartGame();
                            }
                        }, 200);

                    }
                });
            } else {
                waitMoveSpaceItemDTO = null;
                selectedBallYoYo = null;
            }
        }
    }

    private void movePath(List<FancyButton> pathList, FinishCarton finishCarton) {
        List<FancyButton> dotPathList = new LinkedList<>(Arrays.asList(pathList.get(0)));

        FancyButton firstDot = pathList.get(0);
        SpaceItemDTO firstDTO = (SpaceItemDTO) firstDot.getTag();
        if (pathList.size() > 2) {

            FancyButton nextDot = pathList.get(1);
            SpaceItemDTO nextDTO = (SpaceItemDTO) nextDot.getTag();


            // 1上 2下 3左 4右
            int direct = getDirect(firstDTO, nextDTO);


            for (int i = 2; i < pathList.size(); i++) {
                FancyButton dot = pathList.get(i);
                SpaceItemDTO DTO = (SpaceItemDTO) dot.getTag();

                int roDir = getDirect(nextDTO, DTO);
                if (roDir != direct) {
                    dotPathList.add(itemContainerArray[nextDTO.getYNum()][nextDTO.getXNum()]);
                }
                if (i == pathList.size() - 1) {
                    dotPathList.add(itemContainerArray[DTO.getYNum()][DTO.getXNum()]);
                }
                nextDTO = DTO;
            }
        } else {
            dotPathList = new LinkedList<>(pathList);
        }

        IconicsImageView imageView = firstDTO.getBall();

        for (int i = 0; i < dotPathList.size(); i++) {
            FancyButton item1 = dotPathList.get(i);
            if (i + 1 < dotPathList.size()) {
                FancyButton item2 = dotPathList.get(i + 1);
                if (i + 1 == dotPathList.size() - 1) {
                    postDelayed(() -> {
                        startMoveTwoItem(item1, item2, imageView, 100, finishCarton);
                    }, i * 110);
                } else {
                    startMoveTwoItem(item1, item2, imageView, 100, null);
                }
            }
        }
    }

    private void startMoveTwoItem(FancyButton begin, FancyButton end, IconicsImageView imageView, long duration, FinishCarton finishCarton) {
        SpaceItemDTO beginDTO = (SpaceItemDTO) begin.getTag();
        SpaceItemDTO endDTO = (SpaceItemDTO) end.getTag();


        TranslateAnimation translateAnimation = new TranslateAnimation(
                Animation.ABSOLUTE, 0,
                Animation.ABSOLUTE, endDTO.getBallX() - beginDTO.getBallX(),
                Animation.ABSOLUTE, 0,
                Animation.ABSOLUTE, endDTO.getBallY() - beginDTO.getBallY());
        translateAnimation.setFillAfter(true);
        translateAnimation.setDuration(duration);

        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                imageView.clearAnimation();
                RelativeLayout.LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams();
                layoutParams.leftMargin = endDTO.getBallX();
                layoutParams.topMargin = endDTO.getBallY();
                imageView.setLayoutParams(layoutParams);

                if (finishCarton != null) {
                    finishCarton.end();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

        beginDTO.getBall().startAnimation(translateAnimation);


        endDTO.setHasBall(true);
        endDTO.setBall(beginDTO.getBall());
        endDTO.setBallColor(beginDTO.getBallColor());

        beginDTO.setSelected(false);
        beginDTO.setHasBall(false);
        beginDTO.setBallColor(0);
        beginDTO.setBall(null);
    }


    private void showNextBall() {

        for (int color : getNextColors()) {
            postDelayed(() -> {
                FancyButton fancyButton = findNoBallItem();
                SpaceItemDTO spaceItemDTO = (SpaceItemDTO) fancyButton.getTag();

                IconicsImageView ball = new IconicsImageView(getContext());
                RelativeLayout.LayoutParams layoutParams = new LayoutParams(spaceItemDTO.getBallHeight(), spaceItemDTO.getBallHeight());

                layoutParams.topMargin = spaceItemDTO.getBallY();
                layoutParams.leftMargin = spaceItemDTO.getBallX();

                ball.setLayoutParams(layoutParams);
                ball.setColor(color);

                IconicsDrawable iconicsDrawable = new IconicsDrawable(getContext())
                        .icon(FontAwesome.Icon.faw_circle)
                        .color(color);
                ball.setIcon(iconicsDrawable);


                insideContainerLayout.addView(ball);

                YoYo.with(Techniques.BounceIn)
                        .duration(500)
                        .playOn(ball);

                spaceItemDTO.setHasBall(true);
                spaceItemDTO.setBallColor(color);
                spaceItemDTO.setBall(ball);
                spaceItemDTO.setBallX(layoutParams.leftMargin);
                spaceItemDTO.setBallY(layoutParams.topMargin);

                checkAndClearBall(fancyButton);
            }, 200);
        }

        nextColors = null;
        getNextColors();


    }

    private SpaceItemDTO buildEmptySpaceDTO(int height, int i, int j, int center) {
        int ballHeight = height / 3 * 2;
        int gap = (height - ballHeight) / 2;

        SpaceItemDTO spaceItemDTO = new SpaceItemDTO();
        spaceItemDTO.setHasBall(false);
        spaceItemDTO.setYNum(i);
        spaceItemDTO.setXNum(j);
        spaceItemDTO.setItemHeight(height);
        spaceItemDTO.setCenter(center);
        spaceItemDTO.setBallX(spaceItemDTO.getXNum() * height + gap);
        spaceItemDTO.setBallY(spaceItemDTO.getYNum() * height + gap);
        spaceItemDTO.setBallHeight(ballHeight);
        return spaceItemDTO;
    }


    private int randomNum(int min, int max) {
        return (int) (Math.random() * (max - min) + min);
    }

    public void setShowNextBallListener(ShowNextBallListener listener) {
        this.showNextBallListener = listener;
    }

    public void setScoreChangeListener(ScoreChangeListener listener) {
        this.scoreChangeListener = listener;
    }

    private FancyButton findNoBallItem() {
        List<FancyButton> emptyBallList = new LinkedList<>();
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                FancyButton fancyButton = itemContainerArray[i][j];
                SpaceItemDTO spaceItemDTO = (SpaceItemDTO) fancyButton.getTag();
                if (!spaceItemDTO.isHasBall()) {
                    emptyBallList.add(fancyButton);
                }
            }
        }
        if (emptyBallList.isEmpty()) {
            return null;
        }
        int random = randomNum(0, emptyBallList.size() - 1);
        return emptyBallList.get(random);
    }

    private boolean isGameOver() {
        boolean flag = true;
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                FancyButton fancyButton = itemContainerArray[i][j];
                SpaceItemDTO spaceItemDTO = (SpaceItemDTO) fancyButton.getTag();
                if (!spaceItemDTO.isHasBall()) {
                    return false;
                }
            }
        }
        return flag;
    }

    private void checkAndClearBall(FancyButton destBall) {
        SpaceItemDTO spaceItemDTO = (SpaceItemDTO) destBall.getTag();
        int x = spaceItemDTO.getXNum(); // j
        int y = spaceItemDTO.getYNum(); // i

        //横向判断
        List<FancyButton> horList = new LinkedList<>();
        horList.add(destBall);
        int a = 1, b = 1;
        while (a > 0 || b > 0) {
            if (a > 0) {
                if (x + a < ROW) {
                    FancyButton aroundBall = itemContainerArray[y][x + a];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        horList.add(aroundBall);
                        a++;
                    } else {
                        a = 0;
                    }
                } else {
                    a = 0;
                }
            }
            if (b > 0) {
                if (x - b >= 0) {
                    FancyButton aroundBall = itemContainerArray[y][x - b];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        horList.add(aroundBall);
                        b++;
                    } else {
                        b = 0;
                    }
                } else {
                    b = 0;
                }
            }
        }

        // 纵向判断
        List<FancyButton> verList = new LinkedList<>();
        verList.add(destBall);
        a = 1;
        b = 1;
        while (a > 0 || b > 0) {
            if (a > 0) {
                if (y + a < ROW) {
                    FancyButton aroundBall = itemContainerArray[y + a][x];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        verList.add(aroundBall);
                        a++;
                    } else {
                        a = 0;
                    }
                } else {
                    a = 0;
                }
            }
            if (b > 0) {
                if (y - b >= 0) {
                    FancyButton aroundBall = itemContainerArray[y - b][x];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        verList.add(aroundBall);
                        b++;
                    } else {
                        b = 0;
                    }
                } else {
                    b = 0;
                }
            }
        }

        // 左斜向判断
        List<FancyButton> xieList1 = new LinkedList<>();
        xieList1.add(destBall);
        a = 1;
        b = 1;
        while (a > 0 || b > 0) {
            if (a > 0) {
                if (y + a < ROW && x + a < ROW) {
                    FancyButton aroundBall = itemContainerArray[y + a][x + a];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        xieList1.add(aroundBall);
                        a++;
                    } else {
                        a = 0;
                    }
                } else {
                    a = 0;
                }
            }
            if (b > 0) {
                if (y - b >= 0 && x - b >= 0) {
                    FancyButton aroundBall = itemContainerArray[y - b][x - b];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        xieList1.add(aroundBall);
                        b++;
                    } else {
                        b = 0;
                    }
                } else {
                    b = 0;
                }
            }
        }

        // 右斜向判断
        List<FancyButton> xieList2 = new LinkedList<>();
        xieList2.add(destBall);
        a = 1;
        b = 1;
        while (a > 0 || b > 0) {
            if (a > 0) {
                if (y - a >= 0 && x + a < ROW) {
                    FancyButton aroundBall = itemContainerArray[y - a][x + a];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        xieList2.add(aroundBall);
                        a++;
                    } else {
                        a = 0;
                    }
                } else {
                    a = 0;
                }
            }
            if (b > 0) {
                if (y + b < ROW && x - b >= 0) {
                    FancyButton aroundBall = itemContainerArray[y + b][x - b];
                    SpaceItemDTO aroundSpaceItemDTO = (SpaceItemDTO) aroundBall.getTag();
                    if (aroundSpaceItemDTO.isHasBall() && aroundSpaceItemDTO.getBallColor() == spaceItemDTO.getBallColor()) {
                        xieList2.add(aroundBall);
                        b++;
                    } else {
                        b = 0;
                    }
                } else {
                    b = 0;
                }
            }
        }

        Set<FancyButton> clearList = new HashSet<>();

        if (horList.size() >= 5) {
            clearList.addAll(horList);
        }
        if (verList.size() >= 5) {
            clearList.addAll(verList);
        }
        if (xieList1.size() >= 5) {
            clearList.addAll(xieList1);
        }
        if (xieList2.size() >= 5) {
            clearList.addAll(xieList2);
        }

        if (!clearList.isEmpty()) {
            if (scoreChangeListener != null) {
                score += 10 + (clearList.size() - 5) * 2;
                scoreChangeListener.onAddScore(score);
            }
            for (FancyButton e : clearList) {
                clearItem(e);
            }
        }
    }

    private void clearItem(FancyButton itemButton) {
        SpaceItemDTO spaceItemDTO = (SpaceItemDTO) itemButton.getTag();
        spaceItemDTO.setSelected(false);
        spaceItemDTO.setHasBall(false);
        spaceItemDTO.setBallColor(0);

        YoYo.with(Techniques.FadeOut).duration(150).withListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }

            @Override
            public void onAnimationEnd(Animator animator) {
                insideContainerLayout.removeView(spaceItemDTO.getBall());
            }

            @Override
            public void onAnimationCancel(Animator animator) {

            }

            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        }).playOn(spaceItemDTO.getBall());

    }

    // direction:来源方向 0无 1上 2下 3左 4右
    private List<FancyButton> findPathToDest(FancyButton begin, FancyButton end, boolean[][] ballMap) {

        SpaceItemDTO beginSpaceItemDTO = (SpaceItemDTO) begin.getTag();
        SpaceItemDTO endSpaceItemDTO = (SpaceItemDTO) end.getTag();

        List<FancyButton> pathList = new LinkedList<>();

        int x = beginSpaceItemDTO.getXNum(); // j
        int y = beginSpaceItemDTO.getYNum(); // i

        int endX = endSpaceItemDTO.getXNum();
        int endY = endSpaceItemDTO.getYNum();

        List<Integer[]> checkList = new ArrayList<>();
        if (endY < y) {
            if (y - 1 >= 0) {
                checkList.add(new Integer[]{y - 1, x});
            }
        } else if (endY > y) {
            if (y + 1 < ROW) {
                checkList.add(new Integer[]{y + 1, x});
            }
        }
        if (endX < x) {
            if (x - 1 >= 0) {
                checkList.add(new Integer[]{y, x - 1});
            }
        } else if (endX > x) {
            if (x + 1 < ROW) {
                checkList.add(new Integer[]{y, x + 1});
            }
        }

        if (endY < y) {
            if (y + 1 < ROW) {
                checkList.add(new Integer[]{y + 1, x});
            }
        } else {
            if (y - 1 >= 0) {
                checkList.add(new Integer[]{y - 1, x});
            }
        }

        if (endX < x) {
            if (x + 1 < ROW) {
                checkList.add(new Integer[]{y, x + 1});
            }
        } else {
            if (x - 1 >= 0) {
                checkList.add(new Integer[]{y, x - 1});
            }
        }
        Log.d("=======>", "x: " + x + "  y:" + y);
        for (Integer[] intArray : checkList) {
            if (pathList.contains(end)) {
                break;
            } else {
                Log.d("=======>", "intArrayX: " + intArray[0] + "  intArrayY:" + intArray[1]);
                FancyButton nextItem = itemContainerArray[intArray[0]][intArray[1]];
                if (nextItem == end) {
                    return Arrays.asList(begin, end);
                } else {
                    SpaceItemDTO nextDTO = (SpaceItemDTO) nextItem.getTag();
                    if (!nextDTO.isHasBall() && !ballMap[intArray[0]][intArray[1]]) {
                        ballMap[intArray[0]][intArray[1]] = true;
                        List<FancyButton> subPathList = findPathToDest(nextItem, end, copyBallMap(ballMap));
                        if (subPathList.contains(end)) {
                            pathList.add(begin);
                            pathList.addAll(subPathList);
                        }
                    }
                }
            }
        }

        return pathList;
    }

    private boolean[][] getBallMap() {
        boolean[][] ballMap = new boolean[ROW][ROW];
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                FancyButton fancyButton = itemContainerArray[i][j];
                SpaceItemDTO spaceItemDTO = (SpaceItemDTO) fancyButton.getTag();
                ballMap[i][j] = spaceItemDTO.isHasBall();
            }
        }
        return ballMap;
    }

    private boolean[][] copyBallMap(boolean[][] map) {
        boolean[][] ballMap = new boolean[ROW][ROW];
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < ROW; j++) {
                ballMap[i][j] = map[i][j];
            }
        }
        return ballMap;
    }

    // 1 上 2下 3左 4有
    private int getDirect(SpaceItemDTO firstDTO, SpaceItemDTO nextDTO) {
        int direct = 0;
        if (nextDTO.getXNum() - firstDTO.getXNum() > 0) {
            direct = 4;
        } else if (nextDTO.getXNum() - firstDTO.getXNum() < 0) {
            direct = 3;
        } else if (nextDTO.getYNum() - firstDTO.getYNum() > 0) {
            direct = 2;
        } else if (nextDTO.getXNum() - firstDTO.getXNum() < 0) {
            direct = 1;
        }
        return direct;
    }

    private interface FinishCarton {
        default void end() {
        }
    }

    public interface ShowNextBallListener {
        void nextBall(int[] colors);
    }

    public interface ScoreChangeListener {
        void onAddScore(int score);
    }
}
